(() => {
  const startButton = document.getElementById('startButton');
  const board = document.getElementById('board');
  const overlay = document.getElementById('overlay');

  /**
   * Game state
   */
  let secretNumber = null; // 1..100
  let gameStarted = false;
  // Web Audio for explosion SFX
  let audioContext = null;

  function getAudioContext() {
    if (!audioContext) {
      const Ctx = window.AudioContext || window.webkitAudioContext;
      audioContext = new Ctx();
    }
    if (audioContext.state === 'suspended') {
      // On iOS/Safari, resume after user gesture
      audioContext.resume().catch(() => {});
    }
    return audioContext;
  }

  function playExplosion() {
    const ctx = getAudioContext();
    const now = ctx.currentTime;

    // Noise burst with decay
    const duration = 0.8;
    const frames = Math.floor(ctx.sampleRate * duration);
    const noiseBuffer = ctx.createBuffer(1, frames, ctx.sampleRate);
    const data = noiseBuffer.getChannelData(0);
    for (let i = 0; i < frames; i += 1) {
      const t = i / frames;
      const envelope = Math.pow(1 - t, 2); // quick decay
      data[i] = (Math.random() * 2 - 1) * envelope;
    }
    const noise = ctx.createBufferSource();
    noise.buffer = noiseBuffer;
    const lp = ctx.createBiquadFilter();
    lp.type = 'lowpass';
    lp.frequency.setValueAtTime(900, now);
    lp.Q.setValueAtTime(0.7, now);
    const noiseGain = ctx.createGain();
    noiseGain.gain.setValueAtTime(0.9, now);
    noiseGain.gain.exponentialRampToValueAtTime(0.0001, now + duration);
    noise.connect(lp).connect(noiseGain).connect(ctx.destination);
    noise.start(now);
    noise.stop(now + duration);

    // Low thump pitch drop
    const osc = ctx.createOscillator();
    osc.type = 'sine';
    osc.frequency.setValueAtTime(140, now);
    osc.frequency.exponentialRampToValueAtTime(42, now + 0.5);
    const thumpGain = ctx.createGain();
    thumpGain.gain.setValueAtTime(0.6, now);
    thumpGain.gain.exponentialRampToValueAtTime(0.0001, now + 0.5);
    osc.connect(thumpGain).connect(ctx.destination);
    osc.start(now);
    osc.stop(now + 0.5);
  }

  function generateGrid() {
    board.innerHTML = '';
    for (let i = 1; i <= 100; i += 1) {
      const button = document.createElement('button');
      button.className = 'cell';
      button.type = 'button';
      button.textContent = String(i);
      button.setAttribute('role', 'gridcell');
      button.setAttribute('aria-label', `数字 ${i}`);
      button.dataset.value = String(i);
      board.appendChild(button);
    }
  }

  function randomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  }

  function startGame() {
    gameStarted = true;
    startButton.textContent = '重新开始';
    startButton.setAttribute('aria-pressed', 'true');
    overlay.setAttribute('aria-hidden', 'true');
    // Unlock audio on user gesture
    try { getAudioContext(); } catch (_) {}
    // Reset grid
    Array.from(board.children).forEach((el) => {
      el.classList.remove('cell--hidden', 'cell--hit');
      el.disabled = false;
    });
    secretNumber = randomInt(1, 100);
    // console.log('secret', secretNumber);
  }

  function endGame() {
    gameStarted = false;
    startButton.textContent = '重新开始';
    startButton.setAttribute('aria-pressed', 'false');
    overlay.setAttribute('aria-hidden', 'false');
    // Disable remaining cells
    Array.from(board.children).forEach((el) => {
      el.disabled = true;
    });
  }

  function onCellClick(evt) {
    const target = evt.target;
    if (!(target instanceof HTMLElement)) return;
    if (!gameStarted) return;
    const value = Number(target.dataset.value);
    if (!Number.isFinite(value)) return;

    if (value === secretNumber) {
      target.classList.add('cell--hit');
      try { playExplosion(); } catch (_) {}
      endGame();
      return;
    }

    if (value < secretNumber) {
      // hide 1..value
      for (let i = 1; i <= value; i += 1) {
        const el = board.children[i - 1];
        if (el) el.classList.add('cell--hidden');
      }
    } else if (value > secretNumber) {
      // hide value..100
      for (let i = value; i <= 100; i += 1) {
        const el = board.children[i - 1];
        if (el) el.classList.add('cell--hidden');
      }
    }
  }

  // Init
  generateGrid();
  startButton.addEventListener('click', startGame);
  board.addEventListener('click', onCellClick);
})();


